package com.fy.fyspace.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fy.fyspace.common.annotation.GlobalInterceptor;
import com.fy.fyspace.common.result.R;
import com.fy.fyspace.constant.ResultMessageConstant;
import com.fy.fyspace.ex.handler.ExHandler;
import com.fy.fyspace.mapper.UserFeedBackMapper;
import com.fy.fyspace.model.dto.user.UserQueryDTO;
import com.fy.fyspace.model.entity.User;
import com.fy.fyspace.model.entity.UserFeedback;
import com.fy.fyspace.model.vo.feedback.UserFeedbackExportVO;
import com.fy.fyspace.service.MonitorService;
import com.fy.fyspace.service.PerformanceMonitorService;
import com.fy.fyspace.service.UserService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.fy.fyspace.common.result.R.no;
import static com.fy.fyspace.common.result.R.ok;

@Api(tags = "管理员模块接口", description = "提供管理员相关的接口操作")
@Slf4j
@RestController
@RequestMapping("/admin")
public class AdminController {

    @Resource
    private UserService userService;

    @Resource
    private MonitorService monitorService;

    @Resource
    private PerformanceMonitorService performanceMonitorService;

    @Resource
    private UserFeedBackMapper userFeedBackMapper;


    @ApiOperation(value = "获取用户列表", notes = "根据查询条件获取系统用户列表信息，支持分页查询和条件筛选，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @PostMapping("/userList")
    public R list(@ApiParam(value = "用户查询参数") @RequestBody UserQueryDTO userQueryDTO) {
        log.info("查询用户列表/userQueryDTO:{}", userQueryDTO);
        return ok(userService.getUserList(userQueryDTO));
    }

    /**
     * 禁用用户
     * @param id
     * @param status
     * @return
     */
    @ApiOperation(value = "禁用用户", notes = "禁用用户，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @PostMapping("/forbid/{id}/{status}")
    public R disableUser(@ApiParam(value = "用户id") @PathVariable String id, @ApiParam(value = "用户状态") @PathVariable Integer status) {
        log.info("禁用用户/id:{}", id);
        log.info("禁用用户/status:{}", status);
        User user = userService.getById(Long.valueOf(id));
        ExHandler.throwIf(user == null, ResultMessageConstant.USER_NOT_FOUND);
        user.setIsForbid(status);
        boolean b = userService.updateById(user);
        return ok(b);
    }

    /**
     * 导出用户信息表
     * @param month
     * @param response
     */
    @ApiOperation(value = "导出用户信息表", notes = "导出指定月份、指定状态的员工信息表")
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/export")
    public void exportUserExcel(
            @RequestParam(value = "isForbid", required = false) String isForbidStr,
            @RequestParam(value = "month", required = false) String month,
            HttpServletResponse response) {
        // 兼容前端传"null"字符串的情况
        if (month != null && "null".equalsIgnoreCase(month.trim())) {
            month = null;
        }
        Integer isForbid = null;
        if (isForbidStr != null && !"null".equalsIgnoreCase(isForbidStr.trim()) && !isForbidStr.trim().isEmpty()) {
            try {
                isForbid = Integer.valueOf(isForbidStr.trim());
            } catch (NumberFormatException e) {
                // 记录日志，忽略非法isForbid参数
                log.warn("isForbid参数非法: {}", isForbidStr);
            }
        }
        log.info("导出用户信息表/isForbid:{}", isForbid);
        log.info("导出用户信息表/month:{}", month);
        userService.exportUserExcel(isForbid, month, response);
    }

    /**
     * 获取线程池状态
     * @return
     */
    @ApiOperation(value = "获取线程池状态", notes = "查看系统线程池的运行状态，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/threadpool/status")
    public R getThreadPoolStatus() {
        log.info("查询线程池状态");
        try {
            Map<String, Object> status = monitorService.getThreadPoolStatus();
            return ok(status);
        } catch (Exception e) {
            log.error("获取线程池状态失败", e);
            return no("获取线程池状态失败: " + e.getMessage());
        }
    }

    /**
     * 获取系统资源监控（合并应用性能监控数据）
     */
    @ApiOperation(value = "获取系统资源监控", notes = "查看服务器CPU、内存、JVM、类加载等系统资源和应用性能情况，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/system/resources")
    public R getSystemResources() {
        log.info("查询系统资源状态");
        try {
            Map<String, Object> resources = monitorService.getSystemResources();
            return ok(resources);
        } catch (Exception e) {
            log.error("获取系统资源信息失败", e);
            return no("获取系统资源信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取Redis监控信息（结构化、丰富，便于前端渲染）
     */
    @ApiOperation(value = "获取Redis监控信息", notes = "查看Redis连接状态、内存、命令、key、持久化、客户端、复制、CPU等统计信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/redis/status")
    public R getRedisStatus() {
        try {
            Map<String, Object> redisData = monitorService.getRedisStatistics();
            return ok(redisData);
        } catch (Exception e) {
            log.error("获取Redis监控信息失败", e);
            return no("获取Redis监控信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取数据库连接池监控信息
     */
    @ApiOperation(value = "获取数据库连接池监控", notes = "查看HikariCP连接池状态、连接数、等待时间等信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/database/pool")
    public R getDatabasePoolStatus() {
        return monitorService.getDatabasePoolDetailedStatus();
    }

    /**
     * 获取RabbitMQ监控信息
     */
    @ApiOperation(value = "获取RabbitMQ监控信息", notes = "查看RabbitMQ连接状态、队列、交换机等信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/rabbitmq/status")
    public R getRabbitMQStatus() {
        return monitorService.getRabbitMQStatus();
    }

    /**
     * 获取腾讯云COS监控信息
     */
    @ApiOperation(value = "获取腾讯云COS监控信息", notes = "查看腾讯云COS连接状态、存储桶信息等，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/cos/status")
    public R getCosStatus() {
        return monitorService.getCosStatus();
    }

    /**
     * 获取缓存统计信息
     */
    @ApiOperation(value = "获取缓存统计信息", notes = "查看Redis缓存使用情况、键值统计等，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/cache/statistics")
    public R getCacheStatistics() {
        return monitorService.getCacheStatistics();
    }

    /**
     * 获取API调用统计
     */
    @ApiOperation(value = "获取API调用统计", notes = "查看API调用次数、错误率等统计信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/api/statistics")
    public R getApiStatistics() {
        return monitorService.getApiStatistics();
    }

    /**
     * 获取错误日志统计
     */
    @ApiOperation(value = "获取错误日志统计", notes = "查看系统错误日志统计信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/error/statistics")
    public R getErrorLogStatistics() {
        return monitorService.getErrorLogStatistics();
    }

    /**
     * 获取系统告警信息
     */
    @ApiOperation(value = "获取系统告警信息", notes = "查看系统告警、异常等信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/alerts")
    public R getSystemAlerts() {
        return monitorService.getSystemAlerts();
    }

    /**
     * 获取监控仪表板数据
     */
    @ApiOperation(value = "获取监控仪表板数据", notes = "获取综合监控仪表板数据，包括系统概览、性能指标等，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/dashboard")
    public R getDashboardData() {
        return monitorService.getDashboardData();
    }

    /**
     * 获取业务数据统计
     * @return
     */
    @ApiOperation(value = "获取业务数据统计", notes = "查看用户、图片、文件等业务数据的统计信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/business/statistics")
    public R getBusinessStatistics() {
        log.info("查询业务数据统计");
        try {
            Map<String, Object> statistics = monitorService.getBusinessStatistics();
            return ok(statistics);
        } catch (Exception e) {
            log.error("获取业务数据统计失败", e);
            return no("获取业务数据统计失败: " + e.getMessage());
        }
    }

    /**
     * 获取系统健康状态
     */
    @ApiOperation(value = "获取系统健康状态", notes = "综合检查系统各组件健康状态，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/health")
    public R getSystemHealth() {
        log.info("查询系统健康状态");
        try {
            Map<String, Object> health = monitorService.getSystemHealth();
            return ok(health);
        } catch (Exception e) {
            log.error("获取系统健康状态失败", e);
            return no("获取系统健康状态失败: " + e.getMessage());
        }
    }

    /**
     * 导出监控数据
     */
    @ApiOperation(value = "导出监控数据", notes = "导出监控数据为Excel文件，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "导出成功"),
            @ApiResponse(code = 400, message = "导出失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/monitor/export")
    public void exportMonitorData(
            @ApiParam(value = "数据类型", allowableValues = "performance,system,statistics") 
            @RequestParam(defaultValue = "performance") String dataType,
            @ApiParam(value = "开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @ApiParam(value = "结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            HttpServletResponse response) {
        log.info("导出监控数据 - dataType: {}, startTime: {}, endTime: {}", dataType, startTime, endTime);
        monitorService.exportMonitorData(response, dataType, startTime, endTime);
    }

    /**
     * 获取监控配置
     */
    @ApiOperation(value = "获取监控配置", notes = "查看当前监控系统的配置信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/monitor/config")
    public R getMonitorConfig() {
        log.info("查询监控配置");
        try {
            Map<String, Object> config = monitorService.getMonitorConfig();
            return ok(config);
        } catch (Exception e) {
            log.error("获取监控配置失败", e);
            return no("获取监控配置失败: " + e.getMessage());
        }
    }

    /**
     * 重置监控统计数据
     */
    @ApiOperation(value = "重置监控统计数据", notes = "重置API调用计数、错误计数等统计数据，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @PostMapping("/monitor/reset")
    public R resetMonitorStatistics() {
        log.info("重置监控统计数据");
        try {
            String result = monitorService.resetMonitorStatistics();
            return ok(result);
        } catch (Exception e) {
            log.error("重置监控统计数据失败", e);
            return no("重置监控统计数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取性能监控记录
     */
    @ApiOperation(value = "获取性能监控记录", notes = "获取接口性能监控记录，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/performance/records")
    public R getPerformanceRecords(
            @ApiParam(value = "监控名称") @RequestParam(required = false) String monitorName,
            @ApiParam(value = "方法名") @RequestParam(required = false) String methodName,
            @ApiParam(value = "开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @ApiParam(value = "结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNo,
            @ApiParam(value = "每页数量", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize) {
        log.info("查询性能监控记录 - monitorName: {}, methodName: {}, startTime: {}, endTime: {}, pageNo: {}, pageSize: {}", 
                monitorName, methodName, startTime, endTime, pageNo, pageSize);
        return performanceMonitorService.getPerformanceRecords(monitorName, methodName, startTime, endTime, pageNo, pageSize);
    }

    /**
     * 获取性能统计信息
     */
    @ApiOperation(value = "获取性能统计信息", notes = "获取接口性能统计信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/performance/statistics")
    public R getPerformanceStatistics(
            @ApiParam(value = "开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @ApiParam(value = "结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        log.info("查询性能统计信息 - startTime: {}, endTime: {}", startTime, endTime);
        return performanceMonitorService.getPerformanceStatistics(startTime, endTime);
    }

    /**
     * 获取慢查询记录
     */
    @ApiOperation(value = "获取慢查询记录", notes = "获取接口慢查询记录，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/performance/slow-queries")
    public R getSlowQueryRecords(
            @ApiParam(value = "开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @ApiParam(value = "结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNo,
            @ApiParam(value = "每页数量", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize) {
        log.info("查询慢查询记录 - startTime: {}, endTime: {}, pageNo: {}, pageSize: {}", 
                startTime, endTime, pageNo, pageSize);
        return performanceMonitorService.getSlowQueryRecords(startTime, endTime, pageNo, pageSize);
    }

    /**
     * 获取异常记录
     */
    @ApiOperation(value = "获取异常记录", notes = "获取接口异常记录，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/performance/exceptions")
    public R getExceptionRecords(
            @ApiParam(value = "开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @ApiParam(value = "结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNo,
            @ApiParam(value = "每页数量", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize) {
        log.info("查询异常记录 - startTime: {}, endTime: {}, pageNo: {}, pageSize: {}", 
                startTime, endTime, pageNo, pageSize);
        return performanceMonitorService.getExceptionRecords(startTime, endTime, pageNo, pageSize);
    }

    /**
     * 获取接口性能排名
     */
    @ApiOperation(value = "获取接口性能排名", notes = "获取接口平均执行时间排名，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/performance/ranking")
    public R getPerformanceRanking(
            @ApiParam(value = "开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @ApiParam(value = "结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @ApiParam(value = "排名数量", defaultValue = "10") @RequestParam(defaultValue = "10") Integer limit) {
        log.info("查询性能排名 - startTime: {}, endTime: {}, limit: {}", startTime, endTime, limit);
        return performanceMonitorService.getPerformanceRanking(startTime, endTime, limit);
    }

    /**
     * 清理过期性能记录
     */
    @ApiOperation(value = "清理过期性能记录", notes = "清理指定天数之前的性能记录，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @PostMapping("/performance/clean")
    public R cleanExpiredPerformanceRecords(
            @ApiParam(value = "保留天数", defaultValue = "7") @RequestParam(defaultValue = "7") Integer days) {
        log.info("清理过期性能记录 - days: {}", days);
        return performanceMonitorService.cleanExpiredRecords(days);
    }

    /**
     * 测试接口性能
     */
    @ApiOperation(value = "测试接口性能", notes = "对指定接口进行性能测试，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @PostMapping("/performance/test")
    public R testInterfacePerformance(
            @ApiParam(value = "监控名称") @RequestParam String monitorName,
            @ApiParam(value = "测试次数", defaultValue = "10") @RequestParam(defaultValue = "10") Integer testCount) {
        log.info("测试接口性能 - monitorName: {}, testCount: {}", monitorName, testCount);
        return performanceMonitorService.testInterfacePerformance(monitorName, testCount);
    }

    /**
     * 获取MySQL数据库监控统计信息
     */
    @ApiOperation(value = "获取MySQL数据库监控统计", notes = "规范化返回结构，统计MySQL数据库的版本、连接、表、索引、主键、触发器、事件、性能等信息，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 400, message = "请求失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/database/statistics")
    public R getDatabaseStatistics() {
        log.info("查询MySQL数据库监控统计信息");
        return performanceMonitorService.getDatabaseStatistics();
    }

    @ApiOperation(value = "导出用户反馈Excel", notes = "导出筛选后的用户反馈信息为Excel文件，仅管理员可访问")
    @ApiResponses({
            @ApiResponse(code = 200, message = "导出成功"),
            @ApiResponse(code = 400, message = "导出失败")
    })
    @GlobalInterceptor(checkAdmin = true)
    @GetMapping("/feedback/export")
    public void exportFeedbackExcel(
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "contact", required = false) String contact,
            @RequestParam(value = "date", required = false) String date,
            HttpServletResponse response) {
        log.info("导出用户反馈Excel/type:{}, contact:{}, date:{}", type, contact, date);

        try {
            LambdaQueryWrapper<UserFeedback> wrapper = new LambdaQueryWrapper<>();
            if (type != null && !type.trim().isEmpty()) {
                wrapper.eq(UserFeedback::getType, type);
            }
            if (contact != null && !contact.trim().isEmpty()) {
                wrapper.eq(UserFeedback::getContact, contact);
            }
            if (date != null && !date.trim().isEmpty()) {
                // 只筛选当天的反馈
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date start = sdf.parse(date);
                Date end = new Date(start.getTime() + 24 * 60 * 60 * 1000);
                wrapper.ge(UserFeedback::getCreateTime, start);
                wrapper.lt(UserFeedback::getCreateTime, end);
            }
            List<UserFeedback> list = userFeedBackMapper.selectList(wrapper);
            // 转换为导出VO
            SimpleDateFormat sdfFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            List<UserFeedbackExportVO> exportList = list.stream().map(fb -> {
                UserFeedbackExportVO vo = new UserFeedbackExportVO();
                vo.setId(fb.getId());
                vo.setType(fb.getType());
                vo.setDescription(fb.getDescription());
                vo.setContact(fb.getContact());
                vo.setCreateTime(fb.getCreateTime() != null ? sdfFull.format(fb.getCreateTime()) : "");
                vo.setIsRead(fb.getIsRead() != null && fb.getIsRead() == 1 ? "是" : "否");
                return vo;
            }).collect(Collectors.toList());
            // 文件名根据筛选条件自动拼接
            StringBuilder fileNameBuilder = new StringBuilder("用户反馈");
            if (type != null && !type.isEmpty()) fileNameBuilder.append("-").append(type);
            if (contact != null && !contact.isEmpty()) fileNameBuilder.append("-").append(contact);
            if (date != null && !date.isEmpty()) fileNameBuilder.append("-").append(date);
            String fileName = URLEncoder.encode(fileNameBuilder.toString(), "UTF-8");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), UserFeedbackExportVO.class)
                    .sheet("用户反馈")
                    .doWrite(exportList);
        } catch (Exception e) {
            throw new RuntimeException("导出用户反馈信息失败: " + e.getMessage(), e);
        }
    }


    /**
     * 获取用户反馈列表
     * 排序规则：1. 未读在前，已读在后 2. 同一读取状态内按创建时间倒序排序
     */
    @ApiOperation(value = "获取用户反馈列表", notes = "分页获取用户的反馈列表")
    @GetMapping("/feedback/list")
    @GlobalInterceptor(checkAdmin = true)
    public R getUserFeedbackList(@RequestParam(required = false) Integer page,
                                      @RequestParam(required = false) Integer pageSize,
                                      @RequestParam(required = false) String type) {
        try {
            log.info("获取用户反馈列表: page={}, pageSize={}, type={}", page, pageSize, type);

            // 设置默认值
            page = page == null ? 1 : page;
            pageSize = pageSize == null ? 10 : pageSize;

            // 构建查询条件
            LambdaQueryWrapper<UserFeedback> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StringUtils.isNotBlank(type), UserFeedback::getType, type)
                    // 先按已读状态升序（未读在前），再按创建时间倒序
                    .orderByAsc(UserFeedback::getIsRead)
                    .orderByDesc(UserFeedback::getCreateTime);

            // 执行分页查询
            Page<UserFeedback> feedbackPage = new Page<>(page, pageSize);
            Page<UserFeedback> resultPage = userFeedBackMapper.selectPage(feedbackPage, wrapper);

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("total", resultPage.getTotal());
            result.put("records", resultPage.getRecords()); // 改为records以保持一致性

            log.info("获取用户反馈列表成功: total={}, 当前页数据量={}",
                    resultPage.getTotal(), resultPage.getRecords().size());
            return ok(result);

        } catch (Exception e) {
            log.error("获取用户反馈列表失败: error={}", e.getMessage());
            return no(ResultMessageConstant.OPERATION_ERROR);
        }
    }

    /**读取反馈详情
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "获取反馈详情", notes = "读取反馈详情")
    @GetMapping("/feedback/detail/{id}")
    @GlobalInterceptor(checkAdmin = true)
    public R getFeedbackDetail(@PathVariable Long id) {
        try {
            log.info("获取反馈详情: id={}", id);

            // 查询反馈信息
            UserFeedback feedback = userFeedBackMapper.selectById(id);
            ExHandler.throwIf(feedback == null,"反馈不存在");

            // 更新已读状态
            if (feedback.getIsRead() == 0) {
                feedback.setIsRead(1);
                feedback.setCreateTime(new Date());
                userFeedBackMapper.updateById(feedback);
                log.info("更新反馈已读状态: id={}", id);
            }

            log.info("获取反馈详情成功: id={}", id);
            return ok(feedback);

        } catch (Exception e) {
            log.error("获取反馈详情失败: id={}, error={}", id, e.getMessage());
            return no(ResultMessageConstant.OPERATION_ERROR);
        }
    }
}
